<html>

<head>
<title>Fortran 90 documentation</title>
</head>

<body>
<h1>Fortran 90 documentation</h1>

<h2>Data types</h2>

<p> For Fortran 90, ParameterWeaver supports the following data types:
<ol>
  <li> <tt>integer</tt> </li>
  <li> <tt>real</tt> </li>
  <li> <tt>double precision</tt> </li>
  <li> <tt>logical</tt> </li>
  <li> <tt>character(len=1024)</tt> </li>
</ol>
</p>

<h2>Example Fortran 90 program</h2>
<p> Suppose we want to pass command line parameters to the following Fortran program:
<pre>
program main
use iso_fortran_env
implicit none
integer :: unit_nr = 8, i, istat
if (len(trim(out)) &gt; 0) then
    open(unit=unit_nr, file=trim(out), action="write")
else
    unit_nr = output_unit
end if
if (verbose) then
    write (unit_nr, "(A, I20)") "# n = ", n
    write (unit_nr, "(A, F24.15)") "# alpha = ", alpha
    write (unit_nr, "(A, '''', A, '''')") "# out = ", out
    write (unit_nr, "(A, L)") "# verbose = ", verbose
end if
do i = 1, n
    write (unit_nr, "(I3, F5.2)") i, i*alpha
end do
if (unit_nr /= output_unit) then
    close(unit=unit_nr)
end if
stop
end program main
</pre>
We would like to set the number of iterations <tt>n</tt>, the factor <tt>alpha</tt>, the name of the file to write the output to <tt>out</tt> and the verbosity <tt>verbose</tt> at runtime, i.e., without modifying the source code of this program. </p>
<p> Moreover, the code to print the values of the variables is error prone, if we later add or remove a parameter, this part of the code has to be updated as well. </p>
<p> Defining the command line parameters in a parameter definition file to automatlically generate the necessary code simplifies matters considerably. </p>

<h2>Example parameter definition file</h2>
The following file defines four command line parameters named <tt>n</tt>, <tt>alpha</tt>,  <tt>out</tt> and <tt>verbose</tt>.  They are to be interpreted as <tt>integer</tt>, <tt>double precision</tt>, <tt>character(len=1024)</tt> pointer and <tt>logical</tt> respectively, and if no values are passed via the command line, they will have the default values <tt>10</tt>, <tt>0.19</tt>, <tt>output.txt</tt> and false respectively.  Note that a string default value is quoted.  In this case, the columns in the file are separated by tab characters.  The following is the contents of the parameter definition file <tt>param_defs.txt</tt>:
<pre>
integer	n	10
double precision	alpha	0.19
character(len=1024)	out	'output.txt'
logical	verbose	false
</pre>
This parameter definition file can be created in a text editor such as the one used to write the Fortran program, or from a Microsoft Excel worksheet by saving the latter as a CSV file. </p>
<p> As mentioned above, logical values are also supported, however, the semantics is slightly different from other data types.  The default value of a logical variable is always false, regardless of what is specified in the parameter definition file.  As opposed to parameters of other types, a logical parameter acts like a flag, i.e., it is a command line options that doesn't take a value.  Its absence is interpreted as false, its presence as true. </p>

<h2>Generating code</h2>
<p> Generating the code fragments is now very easy.  If appropriate, load the module (VIC3):
<pre>
$ module load parameterweaver
</pre>
Next, we generate the code based on the parameter definition file:
<pre>
$ weave -l Fortran -d param_defs.txt
</pre>
<p> A number of type declarations and functions are generated in the module file <tt>cl_params.f90</tt>.
<ol>
  <li> data structure: a type <tt>params_type</tt> is defined as a <tt>structure</tt> with the parameters as fields, e.g.,
<pre>
    type :: params_type
        integer :: n
        double precision :: alpha
        character(len=1024) :: out
        logical :: verbose
    end type params_type
</pre> </li>
  <li> Initialization function: the default values of the command line parameters are assigned to the fields of the <tt>params_type</tt> variable</li>
  <li> Parsing: the options passed to the program via the command line are assigned to the appropriate fields of the <tt>params_type</tt> variable.  Moreover, the <tt>next</tt> variable of type <tt>integer</tt> will hold the index of the next command line parameter, i.e., the first of the remaining command line parameters that was not handled by the parsing function.  </li>
  <li> Dumper: a function is defined that takes three arguments: a unit number for output, a prefix and the <tt>params_type</tt> variable.  This function writes the values of the command line parameters to the output stream associated with the unit number, each on a separate line, preceeded by the specified prefix. </li>
</ol>
</p>

<h2>Using the code fragments</h2>
<p> The module file is included by the <tt>use</tt> directive:
<pre>
  use cl_parser
</pre>
A variable to hold the parameters has to be defined and its values initialized:
<pre>
  type(params_type) :: params
  call init_cl(params)
</pre>
Next, the command line parameters are parsed and their values assigned:
<pre>
    integer :: next
    call parse_cl(params, next)
</pre>
The dumper can be called whenever the user likes, e.g.,
<pre>
  call dump_cl(output_unit, "", params)
</pre>
The code for the program is thus modified as follows:
<pre>
program main
use cl_params
use iso_fortran_env
implicit none
type(params_type) :: params
integer :: unit_nr = 8, i, istat, next
call init_cl(params)
call parse_cl(params, next)
if (len(trim(params % out)) > 0) then
    open(unit=unit_nr, file=trim(params % out), action="write")
else
    unit_nr = output_unit
end if
if (params % verbose) then
    call dump_cl(unit_nr, "# ", params)
end if
do i = 1, params % n
    write (unit_nr, "(I3, F5.2)") i, i*params % alpha
end do
if (unit_nr /= output_unit) then
    close(unit=unit_nr)
end if
stop
end program main
</pre>
Note that in this example, additional command line parameters are simply ignored.  As mentioned before, they are available using the standard <tt>get_command_argument</tt> function, starting from the value of the variable <tt>next</tt> set by the call to <tt>parse_cl</tt>. </p>

<h2>Using a configuration file</h2>
ParameterWeaver generates a function from the same parameter definition file to parse a configuration file, in addition to command line parameters.  The format of the configuration file, e.g., <tt>config-03.txt' is very straightforward, as the example below illustrates.
<pre>
alpha = 0.19
# comments can be added, as can blank lines
out = 'output-03.txt'

verbose = true
</pre>
Comment lines start with a '#', and are ignored, as are blank lines.</p>
<p>Parsing such a configuration file is now as simple as a single function call:
<pre>
    ...
    call parse_file_cl(params, 'config-03.txt')
    ...
</pre>
Note that both command line parameters and configuration files can be used in the same program, and that their priority is simply determined by the order of calling <tt>parse_cl</tt> and <tt>file_parse_cl</tt>. </p>

</body>

</html>
